#include <util/common_macros.h>
#include <util/msg.h>

#include "../image.h"

void imp_image_histogram(ImpImage * Gray, ImpMatrix ** Hist, boolean normalize) {

	unsigned char * gray;
	real * hist;

	long int imsize;

	_verify(Gray);
	_verify(Hist);

	gray = Gray->data;
	imsize = Gray->npixels;

	if (*Hist == NULL) (*Hist) = imp_matrix_new(1, 256);
	hist = (*Hist)->data;

	{ /* Histogram calculation ============================================== */
		long int i;
		int px;
		for (i = 0; i < imsize; i++) {
			px = gray[i];
			hist[px]++;
		}
	}
	{ /* Normalization ====================================================== */
		int i;
		if (normalize) {
			for (i = 0; i < 256; i++) {
				hist[i] = hist[i] / (real) imsize;
			}
		}
	}

}

void imp_image_histogram_mat(ImpMatrix * Gray, ImpMatrix ** Hist) {

	real * gray;
	real * hist;

	long int imsize;

	_verify(Gray);
	_verify(Hist);

	gray = Gray->data;
	imsize = Gray->size;

	if (*Hist == NULL) (*Hist) = imp_matrix_new(1, 256);
	hist = (*Hist)->data;

	{ /* Histogram calculation ============================================== */
		long int i;
		int px;
		for (i = 0; i < imsize; i++) {
			px = gray[i];
			
			if( px != 0 ) {
				int c;
				c = 10;
			}
			
			hist[px]++;
		}
	}
}


void imp_image_histogram_equalization_mat(ImpMatrix * Mat) {

	//int new_grays_levels = 256;
	real * img;
	int width, height;
	int h, w, k;
	long int sum, hist[256], sum_of_h[256];
	float constant;
	long int imsize;
	long int i;
	int px;

	img = Mat->data;
	width = Mat->columns;
	height = Mat->rows;
	imsize = width * height;
	
	for (i = 0; i < 256; i++) {
		hist[i] = 0;
	}
	
	for (i = 0; i < imsize; i++) {
		px = (int) img[i];
		hist[px]++;
	}


	/* Accumulated histogram */
	sum = 0;
	for (h = 0; h < 256; h++) {
		sum = sum + hist[h];
		sum_of_h[h] = sum;
	}

	/* constant = new # of gray levels div by area */
	constant = 256.0 / (float) (imsize);
	for (h = 0; h < height; h++) {
		for (w = 0; w < width; w++) {
			k = img[h * width + w];
			img[h * width + w] = constant * sum_of_h[k];
		}
	}
}

void imp_image_histogram_equalization(ImpImage * Gray) {

	//int new_grays_levels = 256;
	unsigned char * img;
	int width, height;
	int h, w, k;
	long int sum, hist[256], sum_of_h[256];
	float constant;
	long int imsize;
	long int i;
	int px;

	img = Gray->data;
	width = Gray->width;
	height = Gray->height;
	imsize = width * height;
	
	for (i = 0; i < 256; i++) {
		hist[i] = 0;
	}
	
	for (i = 0; i < imsize; i++) {
		px = img[i];
		hist[px]++;
	}


	/* Accumulated histogram */
	sum = 0;
	for (h = 0; h < 256; h++) {
		sum = sum + hist[h];
		sum_of_h[h] = sum;
	}

	/* constant = new # of gray levels div by area */
	constant = 256.0 / (float) (imsize);
	for (h = 0; h < height; h++) {
		for (w = 0; w < width; w++) {
			k = img[h * width + w];
			img[h * width + w] = constant * sum_of_h[k];
		}
	}
}